package zhongbo.javaweb.instagram.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import zhongbo.javaweb.instagram.enums.RespErrorCode;

/**
 * 说明：rest 返回对象结构封装
 *
 * @author 钟波notebook
 * @since 2020年01月17日 星期五 17:39:40
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "JsonRespDto对象", description = "rest 返回对象结构模型")
public class JsonRespDto<T> {

    /**
     * 状态码
     */
    @ApiModelProperty(value = "状态码")
    private int code;

    /**
     * 状态提示信息
     */
    @ApiModelProperty(value = "状态提示信息")
    private String msg;

    /**
     * 数据
     */
    @ApiModelProperty(value = "数据")
    private T data;

    /**
     * 追加msg提示信息
     *
     * @param append 追加文本
     * @return rest 返回对象
     */
    public JsonRespDto<T> appendMsg(String append) {
        this.msg += append;
        return this;
    }

    public static final class Builder {
        JsonRespDto<Object> instance = new JsonRespDto<>();

        public static final Builder SUCCESS = Builder.newBuilder().setCode(RespErrorCode.SUCCESS.getCode()).setMsg(RespErrorCode.SUCCESS.getMsg()).setData(null);
        public static final Builder ERROR = Builder.newBuilder().setCode(RespErrorCode.ERROR.getCode()).setMsg(RespErrorCode.ERROR.getMsg()).setData(null);

        private Builder() {
        }

        static Builder newBuilder() {
            return new Builder();
        }

        public Builder setCode(int code) {
            instance.code = code;
            return this;
        }

        public Builder errorCode(RespErrorCode errorCode) {
            return this.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
        }

        public Builder setMsg(String msg) {
            instance.msg = msg;
            return this;
        }

        public Builder setData(Object data) {
            instance.data = data;
            return this;
        }

        public JsonRespDto<Object> build() {
            return buildPartial();
        }

        private JsonRespDto<Object> buildPartial() {
            JsonRespDto<Object> respDto = new JsonRespDto<>();
            respDto.code = instance.code;
            respDto.msg = instance.msg;
            respDto.data = instance.data;
            return respDto;
        }
    }

    /**
     * 请求成功响应
     *
     * @return 成功响应对象
     */
    public JsonRespDto<T> makeSuccess() {
        this.code = RespErrorCode.SUCCESS.getCode();
        this.msg = RespErrorCode.SUCCESS.getMsg();
        return this;
    }

    /**
     * 请求失败响应
     *
     * @return 失败响应对象
     */
    public JsonRespDto<T> makeError() {
        this.code = RespErrorCode.ERROR.getCode();
        this.msg = RespErrorCode.ERROR.getMsg();
        return this;
    }

    /**
     * 指定错误码的请求失败响应
     *
     * @param errorCode 错误码枚举
     * @return 失败响应对象
     */
    public JsonRespDto<T> makeError(RespErrorCode errorCode) {
        if (null == (errorCode)) {
            makeError();
        } else {
            this.code = errorCode.getCode();
            this.msg = errorCode.getMsg();
        }
        return this;
    }

    /**
     * 指定错误码的请求失败响应
     *
     * @param errorCode 自定义错误码代码
     * @return 失败响应对象
     */
    public JsonRespDto<T> makeError(int errorCode) {
        this.code = errorCode;
        return this;
    }

    /**
     * 指定错误码的请求失败响应
     *
     * @param errorCode 自定义错误码代码
     * @param message   自定义状态提示信息
     * @return 失败响应对象
     */
    public JsonRespDto<T> makeError(int errorCode, String message) {
        this.code = errorCode;
        this.msg = message;
        return this;
    }

    /**
     * 设置响应数据内容
     *
     * @param data 响应数据内容
     * @return 响应对象
     */
    public JsonRespDto<T> setData(T data) {
        this.data = data;
        return this;
    }

    /**
     * 成功响应信息
     *
     * @return 成功响应对象
     */
    public static JsonRespDto<Object> success() {
        return new JsonRespDto<>(RespErrorCode.SUCCESS.getCode(), RespErrorCode.SUCCESS.getMsg(), null);
    }

    /**
     * 失败响应信息
     *
     * @return 失败响应对象
     */
    public static JsonRespDto<Object> error() {
        return new JsonRespDto<>(RespErrorCode.ERROR.getCode(), RespErrorCode.ERROR.getMsg(), null);
    }

    /**
     * 指定错误码的失败响应信息
     *
     * @param errorCode 错误码枚举
     * @return 失败响应对象
     */
    public static JsonRespDto<Object> error(RespErrorCode errorCode) {
        if (errorCode != null) {
            return new JsonRespDto<>(errorCode.getCode(), errorCode.getMsg(), null);
        } else {
            return error();
        }
    }
}
